package com.olap.starter.core.handler;

import com.olap.starter.core.exception.OnlineException;
import com.olap.starter.core.response.Result;
import com.olap.starter.core.response.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import jakarta.servlet.http.HttpServletRequest;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author WBG
 * @date 2021/9/8 8:09
 * @describe 全局异常处理器
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandlerOlp {
    /**
     * 业务异常
     */
    @ExceptionHandler(OnlineException.class)
    public Result handleServiceException(OnlineException e, HttpServletRequest request) {
        log.error(e.getMessage());
        return ResultUtil.error(e.getMessage());
    }

    @ExceptionHandler(value = Exception.class)
    public Result<?> defaultExceptionHandler(HttpServletRequest req, Throwable ex) {
        //ex.printStackTrace();
        log.error("[defaultExceptionHandler]", ex);
        // 返回 ERROR CommonResult
        return ResultUtil.error(500, ex.getMessage());
    }

    @ExceptionHandler(value = RuntimeException.class)
    public Result<?> defaultRuntimeException(HttpServletRequest req, Throwable ex) {
        //ex.printStackTrace();
        String msg = ex.getMessage();
        if (ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
            String errorMessage = ex.getMessage();
            // 正则匹配唯一索引冲突
            Pattern pattern = Pattern.compile("Duplicate entry '(.*?)' for key '(.*?)'");
            Matcher matcher = pattern.matcher(errorMessage);
            String tableName = extractTableNameFromSQL(errorMessage);
            msg = "表名[" + tableName + "]数据已存在";
            if (matcher.find()) {
                String value = matcher.group(1);
                String indexName = matcher.group(2);
                msg += "，检索字段[" + indexName + "]值[" + value + "]";
            }
            log.error(msg);
        }

        log.error("[defaultRuntimeException]", ex);
        return ResultUtil.error(500, msg);
    }

    private static String extractTableNameFromSQL(String sql) {
        if (sql != null) {
            // 匹配 INSERT INTO 后的表名（忽略大小写）
            Pattern pattern = Pattern.compile("INSERT\\s+INTO\\s+(\\w+)", Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(sql);
            if (matcher.find()) {
                return matcher.group(1);
            }
        }
        return "未知表";
    }
}
